const { think } = require('thinkjs');
const Base = require('./base.js');
const moment = require('moment/moment.js');
const { default: BigNumber } = require('bignumber.js');
const { getField } = require('../model/jisuan.js');

module.exports = class extends Base {
  async contractPanelAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const contract_num = await this.model('contract_list')
      .where({ type: ['IN', '1,2'] })
      .count();
    const contract_num_jiafang = await this.model('contract_list')
      .where({ type: 2, date_start: ['between', [start, end]] })
      .count();
    const contract_sum_fangzu = await this.model('contract_list')
      .where({ type: 1, date_start: ['between', [start, end]] })
      .sum('fangzu');
    const contract_sum_wuye = await this.model('contract_list')
      .where({ type: 1, date_start: ['between', [start, end]] })
      .sum('wuye');
    const contract_sum = BigNumber(contract_sum_fangzu)
      .plus(BigNumber(contract_sum_wuye))
      .toFixed(2);

    const royalty = await this.model('output_list')
      .where({
        type: 'royalty',
        status: 1,
        update_time: ['between', [start, end]],
      })
      .sum('money');

    const contract_daoqi = await this.model('contract_list')
      .where({
        type: 1,
        date_end: [
          'between',
          moment().format('YYYY-MM-DD'),
          moment()
            .add(6, 'months')
            .format('YYYY-MM-DD'),
        ],
      })
      .count();
    const contract_guakao = await this.model('contract_list')
      .where({
        type: 3,
        contract_type: 70,
        date_end: [
          'between',
          moment().format('YYYY-MM-DD'),
          moment()
            .add(6, 'months')
            .format('YYYY-MM-DD'),
        ],
      })
      .count();
    const contract_guoqi = await this.model('contract_list')
      .where({
        status: 2,
        type: 1,
      })
      .count();
    return this.success({
      contract_num: contract_num,
      contract_num_jiafang: contract_num_jiafang,
      contract_sum: contract_sum,
      royalty: royalty,
      contract_daoqi: contract_daoqi,
      contract_guakao,
      contract_guoqi,
    });
  }

  async contractCycleAction() {
    const dateFilter = this.post('t');
    const start = moment(dateFilter[0]);
    const startData = moment(dateFilter[0]);
    const end = moment(dateFilter[1]);

    const data = {
      data: [],
    };
    const xData = [];
    const num = end.diff(start, 'months');

    for (let i = 0; i < num; i++) {
      xData.push(start.add(1, 'months').format('YYYY-MM'));
    }

    data.xData = xData;

    for (let i = 0; i < num; i++) {
      const total = await this.model('contract_list')
        .where({
          type: ['IN', '1,2,3'],
          date_start: [
            'between',
            moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
            startData
              .add(1, 'months')
              .endOf('month')
              .format('YYYY-MM-DD HH:MM'),
          ],
        })
        .count();
      data.data.push(total);
    }

    return this.success(data);
  }

  async contractCatgoryAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const contract_sum_fangzu =
      (await this.model('contract_list')
        .where({ type: 1, date_start: ['between', [start, end]] })
        .sum('fangzu')) || 0;
    const contract_sum_wuye =
      (await this.model('contract_list')
        .where({ type: 1, date_start: ['between', [start, end]] })
        .sum('wuye')) || 0;
    const contract_sum_zengzhi =
      (await this.model('contract_list')
        .where({ type: 3, date_start: ['between', [start, end]] })
        .sum('contract_total')) || 0;

    const contract_sum = BigNumber(contract_sum_fangzu)
      .plus(BigNumber(contract_sum_wuye))
      .toFixed(2);
    return this.success([
      { name: '租赁合同', value: contract_sum },
      { name: '增值合同', value: contract_sum_zengzhi },
    ]);
  }

  async contractProjectAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const project = await this.model('project_list')
      .where({ type: 1 })
      .field('name, id')
      .select();
    const arr = [];
    for (const item of project) {
      const list = await this.model('contract_list')
        .where({
          project_id: item.id,
          type: ['!=', 2],
          date_start: ['between', [start, end]],
        })
        .field('wuye, fangzu, contract_total, type')
        .select();
      let total = BigNumber(0);
      for (const listItem of list) {
        if (listItem.type == 3) {
          total = total.plus(BigNumber(listItem.contract_total));
        } else if (listItem.type == 1) {
          total = total
            .plus(BigNumber(listItem.wuye))
            .plus(BigNumber(listItem.fangzu));
        }
      }
      arr.push({
        name: item.name,
        value: total.toFixed(2),
      });
    }
    return this.success(arr);
  }

  async contractLineAction() {
    const dateFilter = this.post('t');

    const start = moment();
    const end = moment().add(3, 'years');

    const project = await this.model('project_list')
      .where({ type: 1 })
      .field('name, id')
      .select();

    // const days = [end];

    const num = end.diff(start, 'months');

    const data = {
      data: [],
    };

    const xData = [];

    for (const item of project) {
      item.startData = moment();
    }

    for (let i = 0; i < num; i++) {
      xData.push(start.add(1, 'months').format('YYYY-MM'));
    }

    data.xData = xData;
    data.legend = {};

    for (let i = 0; i < project.length; i++) {
      const addData = {
        name: project[i].name,
        type: 'bar',
        barWidth: '60%',
        showSymbol: false,
        stack: 'Total',
        data: [],
      };
      data.legend[project[i].name] = i === 0 ? true : false;

      const list = await this.model('contract_line')
        .where({
          project_id: project[i].id,
        })
        .getField('total', false);

      addData.data = list;
      data.data.push(addData);
    }
    return this.success(data);
  }

  async financePanelAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const incomeTotal =
      (await this.model('income_list')
        .where({
          status: 1,
          type: ['!=', 'yajin'],
          update_time: ['between', [start, end]],
        })
        .sum('money')) || 0;
    const outputTotal =
      (await this.model('output_list')
        .where({ status: 1, update_time: ['between', [start, end]] })
        .sum('money')) || 0;
    const yajinInTotal =
      (await this.model('income_list')
        .where({
          status: 1,
          type: 'yajin',
          update_time: ['between', [start, end]],
        })
        .sum('money')) || 0;
    const yajinOutTotal =
      (await this.model('output_list')
        .where({
          status: 1,
          type: 'yajin',
          update_time: ['between', [start, end]],
        })
        .sum('money')) || 0;

    const unInTotal =
      (await this.model('income_list')
        .where({
          status: 0,
          type: ['!=', 'yajin'],
          delay: 1,
          pass: 0,
        })
        .sum('money')) || 0;

    const unOutTotal =
      (await this.model('output_list')
        .where({ status: 0, type: ['!=', 'yajin'], delay: 1 })
        .sum('money')) || 0;

    const unBaseTotal =
      (await this.model('output_list')
        .where({ status: 0, type: 'base' })
        .sum('money')) || 0;

    return this.success({
      incomeTotal: incomeTotal,
      outputTotal: outputTotal,
      lirunTotal: BigNumber(incomeTotal)
        .minus(BigNumber(outputTotal))
        .toFixed(2),
      yajinInTotal: yajinInTotal,
      yajinOutTotal: yajinOutTotal,
      unInTotal: unInTotal,
      unOutTotal: unOutTotal,
      unBaseTotal,
    });
  }

  async financeLineAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]);
    const end = moment(dateFilter[1]);

    const types = [
      {
        name: '收入',
        type: 'bar',
        startData: moment(dateFilter[0]),
      },
      {
        name: '支出',
        type: 'bar',
        startData: moment(dateFilter[0]),
      },
      {
        name: '利润',
        type: 'line',
        startData: moment(dateFilter[0]),
      },
    ];

    const data = {
      data: [],
    };
    const xData = [];
    const num = end.diff(start, 'months');

    for (let i = 0; i < num; i++) {
      xData.push(start.add(1, 'months').format('YYYY-MM'));
    }

    data.xData = xData;

    for (const item of types) {
      const addData = {
        name: item.name,
        type: item.type,
        showSymbol: false,
        data: [],
        tooltip: {
          // valueFormatter: function(value) {
          //   return value + ' °C';
          // },
        },
      };

      for (let i = 0; i < num; i++) {
        if (item.name === '收入') {
          const totalIncome =
            (await this.model('income_list')
              .where({
                status: 1,
                type: ['!=', 'yajin'],
                update_time: [
                  'between',
                  moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
                  item.startData
                    .add(1, 'months')
                    .endOf('month')
                    .format('YYYY-MM-DD HH:MM'),
                ],
              })
              .sum('money')) || 0;
          addData.data.push(totalIncome);
        } else if (item.name === '支出') {
          const totalOutput =
            (await this.model('output_list')
              .where({
                status: 1,
                update_time: [
                  'between',
                  moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
                  item.startData
                    .add(1, 'months')
                    .endOf('month')
                    .format('YYYY-MM-DD HH:MM'),
                ],
              })
              .sum('money')) || 0;
          addData.data.push(totalOutput);
        } else {
          const n = BigNumber(data.data[0].data[i])
            .minus(BigNumber(data.data[1].data[i]))
            .toFixed(2);
          addData.data.push(n);
        }
      }
      data.data.push(addData);
    }
    return this.success(data);
  }

  async financeShouzhiAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const income = await this.model('income_list')
      .where({
        type: ['!=', 'yajin'],
        status: 1,
        update_time: ['between', [start, end]],
      })
      .sum('money');
    const output = await this.model('output_list')
      .where({ status: 1, update_time: ['between', [start, end]] })
      .sum('money');
    const arr = [
      {
        name: '收入',
        value: income || 0,
      },
      {
        name: '支出',
        value: output || 0,
      },
    ];

    return this.success(arr);
  }

  async financeYajinAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const list = await this.model('income_list')
      .where({
        type: 'yajin',
        status: 1,
        update_time: ['between', [start, end]],
      })
      .select();
    const arr = [];
    for (const item of list) {
      const has = arr.find((res) => {
        if (res.name === item.yajin_type_str) {
          res.value = BigNumber(res.value)
            .plus(BigNumber(item.money))
            .toFixed(2);
        }
        return res.name === item.yajin_type_str;
      });
      if (!has) {
        arr.push({
          name: item.yajin_type_str,
          value: item.money || 0,
        });
      }
    }
    return this.success(arr);
  }

  async financeCatgoryAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');

    const dict = [
      { label: '押金', value: 'yajin' },
      { label: '水电', value: 'shuidian' },
      { label: '租赁', value: 'fangzu' },
      { label: '物业', value: 'wuye' },
    ];
    const list = await this.model('income_list')
      .where({ status: 1, update_time: ['between', [start, end]] })
      .select();
    const arr = [];
    for (const item of list) {
      let typeName;

      dict.forEach((element) => {
        if (element.value === item.type) {
          typeName = element;
        }
      });
      if (!typeName) {
        continue;
      }

      const has = arr.find((res) => {
        if (res.name === typeName.label) {
          res.value = BigNumber(res.value)
            .plus(BigNumber(item.money))
            .toFixed(2);
        }
        return res.name === typeName.label;
      });
      if (!has) {
        arr.push({
          name: typeName.label,
          value: item.money || 0,
        });
      }
    }
    return this.success(arr);
  }

  async financeOutputAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]);
    const end = moment(dateFilter[1]);

    const dict = [
      { label: '房租', value: 'fangzu', startData: moment(dateFilter[0]) },
      { label: '基础成本', value: 'base', startData: moment(dateFilter[0]) },
      { label: '员工支出', value: 'staff', startData: moment(dateFilter[0]) },
      { label: '提成', value: 'royalty', startData: moment(dateFilter[0]) },
      {
        label: '招商成本',
        value: 'bussiness',
        startData: moment(dateFilter[0]),
      },
      { label: '内部管理', value: 'team', startData: moment(dateFilter[0]) },
      { label: '经营管理', value: 'manage', startData: moment(dateFilter[0]) },
      { label: '水电支出', value: 'utility', startData: moment(dateFilter[0]) },
    ];

    const data = {
      data: [],
    };

    const xData = [];
    const num = end.diff(start, 'months');

    for (let i = 0; i < num; i++) {
      xData.push(start.add(1, 'months').format('YYYY-MM'));
    }

    data.xData = xData;

    for (const dictItem of dict) {
      const addData = {
        name: dictItem.label,
        type: 'bar',
        stack: 'total',
        // label: {
        //   show: true,
        // },
        // emphasis: {
        //   focus: 'series',
        // },
        barWidth: 25,
        data: [],
        // tooltip: {
        //   valueFormatter: function(value) {
        //     return value + ' °C';
        //   },
        // },
      };
      for (let i = 0; i < num; i++) {
        const totalOutput =
          (await this.model('output_list')
            .where({
              status: 1,
              type: dictItem.value,
              update_time: [
                'between',
                moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
                dictItem.startData
                  .add(1, 'months')
                  .endOf('month')
                  .format('YYYY-MM-DD HH:MM'),
              ],
            })
            .sum('money')) || 0;
        addData.data.push(totalOutput);
      }
      data.data.push(addData);
    }
    return this.success(data);
  }

  async utiltyPanelAction() {
    const dateFilter = this.post('t');
    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');
    const total = await this.model('income_list')
      .where({
        status: 1,
        type: 'shuidian',
        update_time: ['between', [start, end]],
      })
      .sum('money');
    const totalOutput = await this.model('output_list')
      .where({
        status: 1,
        type: 'utility',
        update_time: ['between', [start, end]],
      })
      .sum('money');
    const untotal = await this.model('income_list')
      .where({
        status: 0,
        type: 'shuidian',
        create_time: ['between', [start, end]],
      })
      .sum('money');
    const unPay = await this.model('output_list')
      .where({
        status: 0,
        type: 'utility',
        update_time: ['between', [start, end]],
      })
      .sum('money');
    return this.success({
      total: total,
      totalOutput: totalOutput,
      untotal: untotal || 0,
      unPay: unPay || 0,
    });
  }

  async utiltyLineAction() {
    const dateFilter = this.post('t');

    const start = moment(dateFilter[0]);
    // const s = moment(dateFilter[0]).format('YYYY-MM-DD HH:MM');
    const end = moment(dateFilter[1]);

    const types = [
      {
        name: '收入',
        type: 'bar',
        startData: moment(dateFilter[0]),
      },
      {
        name: '支出',
        type: 'bar',
        startData: moment(dateFilter[0]),
      },
    ];

    const data = {
      data: [],
    };

    const xData = [];
    const num = end.diff(start, 'months') + 1;

    for (let i = 0; i < num; i++) {
      xData.push(start.format('YYYY-MM'));
      start.add(1, 'months');
    }
    data.xData = xData;

    for (const item of types) {
      const addData = {
        name: item.name,
        type: item.type,
        showSymbol: false,
        data: [],
        tooltip: {
          valueFormatter: function(value) {
            return value + ' °C';
          },
        },
      };

      for (let i = 0; i < num; i++) {
        const searchEnd = {
          update_time: [
            'between',
            item.startData.startOf('month').format('YYYY-MM-DD'),
            item.startData.endOf('month').format('YYYY-MM-DD'),
          ],
        };

        let model, query;

        if (item.name === '收入') {
          model = this.model('income_list');
          query = { type: 'shuidian' };
        } else if (item.name === '支出') {
          model = this.model('output_list');
          query = { type: 'utility' };
        }

        item.startData.add(1, 'months');

        const total = await model
          .where(
            Object.assign(
              {
                status: 1,
              },
              query,
              searchEnd
            )
          )
          .sum('money');

        addData.data.push(total || 0);
      }
      data.data.push(addData);
    }
    return this.success(data);
  }

  async utiltyShouzhiAction() {
    const dateFilter = this.post('t');
    const start = moment(dateFilter[0]).format('YYYY-MM-DD');
    const end = moment(dateFilter[1]).format('YYYY-MM-DD');
    const income = await this.model('income_list')
      .where({
        status: 1,
        type: 'shuidian',
        update_time: ['between', [start, end]],
      })
      .sum('money');
    const output = await this.model('output_list')
      .where({
        status: 1,
        type: 'utility',
        update_time: ['between', [start, end]],
      })
      .sum('money');
    const arr = [
      {
        name: '收入',
        value: income || 0,
      },
      {
        name: '支出',
        value: output || 0,
      },
    ];
    return this.success(arr);
  }

  async utiltyZoushiAction() {
    const dateFilter = this.post('t');
    const start = moment(dateFilter[0]);
    const end = moment(dateFilter[1]);
    const types = [
      {
        name: '收入',
        type: 'line',
        startData: moment(dateFilter[0]),
      },
      {
        name: '支出',
        type: 'line',
        startData: moment(dateFilter[0]),
      },
    ];
    const data = {
      data: [],
    };
    const xData = [];
    const num = end.diff(start, 'months');
    for (let i = 0; i < num; i++) {
      xData.push(start.add(1, 'months').format('YYYY-MM'));
    }
    data.xData = xData;
    for (const item of types) {
      const addData = {
        name: item.name,
        type: item.type,
        showSymbol: false,
        data: [],
        tooltip: {
          valueFormatter: function(value) {
            return value + ' °C';
          },
        },
      };
      for (let i = 0; i < num; i++) {
        if (item.name === '收入') {
          const totalIncome =
            (await this.model('income_list')
              .where({
                status: 1,
                type: 'shuidian',
                update_time: [
                  'between',
                  moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
                  item.startData
                    .add(1, 'months')
                    .endOf('month')
                    .format('YYYY-MM-DD HH:MM'),
                ],
              })
              .sum('money')) || 0;
          addData.data.push(totalIncome);
        } else if (item.name === '支出') {
          const totalOutput =
            (await this.model('output_list')
              .where({
                status: 1,
                type: 'utility',
                update_time: [
                  'between',
                  moment('2000-01-01').format('YYYY-MM-DD HH:MM'),
                  item.startData
                    .add(1, 'months')
                    .endOf('month')
                    .format('YYYY-MM-DD HH:MM'),
                ],
              })
              .sum('money')) || 0;
          addData.data.push(totalOutput);
        }
      }
      data.data.push(addData);
    }
    return this.success(data);
  }
};
